package apiserver

import (
	"fmt"
	"git.hortorgames.com/orange/tang/lua"
	"git.hortorgames.com/orange/tang/mongo"
	"sync"
)

type scriptType string

const scriptTypeFilter = "filter"
const scriptTypeExt = "ext"

type Pool struct {
	sync.Once
	*lua.Pool
	cache *sync.Map
}

func (p *Pool) Get(ctx *Context, scriptType scriptType) (*lua.PooledLState, error) {
	gameId := ctx.Game.Id
	path := ctx.Request().URL.Path
	key := fmt.Sprintf("%s:%s", gameId, path)
	if v, ok := p.cache.Load(key); ok {
		if v == nil {
			return nil, nil
		}
		return p.Pool.Get(v.(string)), nil
	}

	//p.cache.Store(key, nil)
	//return nil, nil

	var obj mongo.M
	var script string
	err := ctx.UsingMongoSession(func(sess *mongo.Session) error {
		return sess.C(string(scriptType)+"s").FindOne(mongo.M{"_id": path}, &obj)
	})
	if err != nil && err != mongo.ErrNoDocuments {
		p.cache.Store(key, nil)
		return nil, err
	}
	err = nil
	script, _ = obj["script"].(string)
	if len(script) == 0 {
		p.cache.Store(key, nil)
		return nil, nil
	}
	p.cache.Store(key, script)
	return p.Pool.Get(script), nil
}

var scripts Pool

func Scripts() *Pool {
	scripts.Do(func() {
		scripts.Pool = lua.NewPool(nil)
		scripts.cache = &sync.Map{}
	})
	return &scripts
}
